/************************************************************************************
 * Name: GetSmsReply
 * Object: Case, Contact, WorkOrder__c
 * Purpose: 从短信服务商取得满意度调查短信回复，然后更新个案和工单的满意度
 * Requirement:
 * Author: kittylau (382376269@qq.com)
 * Create Date: 2017-01-16
 * Modify History: 
 *
 * 得到回复结果例子：
 *  result=0&confirm_time=2017-01-15 17:15:49&id=2298180600&
 * replys=[{"callmdn":"106902338128283720","mdn":"13929512501","content":"A","reply_time":"2017-01-15 17:11:58","id":"2298180561"},{"callmdn":"1069064011283720","mdn":"18122266563","content":"A","reply_time":"2017-01-15 17:15:49","id":"2298180600"}]
 *
 * replys参数说明：
 * mdn          手机号码
 * callmdn      接入号
 * content      回复内容
 * reply_time   回复时间，格式yyyy-MM-dd HH:mm:ss
 * id           回复id编号
 ************************************************************************************/
global without sharing class GetSmsReply  {//implements Schedulable
    public void test(){
        
    }
    /*
    global void execute(SchedulableContext sc) {
        // 从短信服务器得到短信回复
        getSmsFromService();
        // 设置超过一天没有回复
        setDefaultSatisfaction();
    }

    // private Long maxID;

    private static Map<String, String> answerMap = new Map<String, String> {
        'A' => '非常满意',
        'B' => '满意',
        'C' => '处理结果不满意',
        'D' => '技术能力不满意',
        'E' => '响应时间不满意',
        'F' => '服务过程投诉'
    };

    // 如果超过一天没有满意度调查回复，满意度自动设置
     
     
    public void setDefaultSatisfaction() {
        try {
            // 检索没有接收到满意度回复短信的数据
            List<Case> clist = new List<Case>();
            for (Case c : [select Id, SendSatisfyTime__c from Case where ReceiveSatisfyTime__c = null and SendSatisfyTime__c != null]) {
                // 如果现在-满意度短信发送时间超过一天
                if ((Datetime.now().getTime() - c.SendSatisfyTime__c.getTime()) / 1000 / 60 / 60 / 24 > 1) {
                    c.ClientEvaluation__c = '客户未回复短信';
                    c.ReceiveSatisfyTime__c = Datetime.now();
                    clist.add(c);
                }
            }
            if (clist.size() > 0) update clist;
        } catch(Exception ex) {
            System.debug('*** 自动设置满意度时出错：' + ex.getMessage());
        }  
    }

    
     // 从短信服务商读取短信回复(客户满意度调查回复)
     
    public void getSmsFromService() {
        try {
            //生成取短信回复URL
            smsApi__c sms = smsApi__c.getValues('SMS_Setting');
            //用来从短信服务商取回复内容的URL
            String urlReply = sms.reply_URL__c;
            urlReply += '?SpCode=' + sms.SpCode__c ; //企业号
            urlReply += '&LoginName=' + sms.LoginName__c ;//登录用户名
            urlReply += '&Password=' + sms.Password__c; //登录用户密码

            //生成POST请求
            HttpRequest req = new HttpRequest();
            req.setEndpoint(urlReply); 
            req.setMethod('POST');
            //发送短信并取得返回结果
            HttpResponse res = Utils.postRequest(req,5); 
            //必须设置编码为GB2312或GBK，否则读取数据时会乱码
            res.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=GB2312');
            String result = res.getBody();
            
            Long maxID = 0;
            //分析返回结果
            Integer index = result.indexOf('&replys');
            //有短信回复
            if (index > 0) {
                result = result.substring(index + 8);
                result = '{"replys":' + result + '}';

                System.debug('*** 短信回复内容（Json样式): ' + result);

                //用来记录回复人电话和回复内容对应关系
                Map<String,List<String>> mapReply = new Map<String,List<String>>();
                JSONParser parser = JSON.createParser(result);
                while (parser.nextToken() != null) {
                    // 开始读取回复(根结点)
                    if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
                        // 循环读取回复
                        while (parser.nextToken() != null) {
                            if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                                //转化后对象
                                SmsReplyArgs args = (SmsReplyArgs)parser.readValueAs(SmsReplyArgs.class);
                                if (args.id > maxID) {
                                    maxID = args.id;
                                }
                                //如果没有记录，则记录
                                if (!mapReply.containsKey(args.mdn)) {
                                    mapReply.put(args.mdn, new List<String>{args.content});
                                } else {
                                    mapReply.get(args.mdn).Add(args.content);
                                }
                                //读取下一条回复
                                parser.skipChildren();
                            }
                        }   
                    }
                }
                
                //如果有短信回复
                if (mapReply.size() > 0) {
                    // for (String r : mapReply.keySet()) {
                    //     System.debug('rrrrrrrrrrr:'+r);
                    //     System.debug('oooooooooooo:'+mapReply.get(r)[0]);
                    // }
                    //记录要保存的个案
                    List<Case> saveList = new List<Case>();

                    List<Case> clist = [select Id, Contact.MobilePhone from Case where ReceiveSatisfyTime__c = null and SendSatisfyTime__c != null and ClientEvaluation__c = null and Contact.MobilePhone in :mapReply.keySet()];
                    if (clist.size() > 0) {
                        Map<String, Case> caseMap = new Map<String, Case>();
                        for (Case c : clist) {
                            caseMap.put(c.Contact.MobilePhone, c);
                        }

                        for (String reply : mapReply.keySet()) {
                            if (caseMap.containsKey(reply)) {
                                List<String> contents = mapReply.get(reply);
                                Case newc = caseMap.get(reply);

                                String scon = contents[0].trim().toUpperCase();
                                // 如果是标准回复(ABCDEF)
                                if (scon == 'A' || scon == 'B' || scon == 'C' || scon == 'D' || scon == 'E' || scon == 'F') {
                                    newc.ClientEvaluation__c = answerMap.get(scon);
                                }
                                //如果不是标准回复
                                else {
                                    newc.ClientEvaluation__c = scon;
                                    newc.DummySms__c = true;
                                }
                                newc.ReceiveSatisfyTime__c = System.now();
                                saveList.add(newc);
                            }
                        }
                    }

                    try {
                        //保存满意度数据
                        update saveList;
                    } catch(Exception e) {
                        System.debug(LoggingLevel.ERROR, '*** 错误信息: ' + e.getMessage() );
                    }

                    notifyServer(maxID);
                }
            }
        } catch(Exception ex) {
            System.debug(LoggingLevel.ERROR, '*** 读取短信回复或处理回复时错误: ' + ex.getMessage());
        }
    }

    @future(callout=true)
    public static void notifyServer(Long maxID) {
        if (maxID > 0) {
            //生成取短信回复URL
            smsApi__c sms = smsApi__c.getValues('SMS_Setting');
            //用来通知短信服务商回复内容已读取的URL
            String urlConfirm = sms.replyConfirm_URL__c;
            urlConfirm += '?SpCode=' + sms.SpCode__c ; //企业号
            urlConfirm += '&LoginName=' + sms.LoginName__c ;//登录用户名
            urlConfirm += '&Password=' + sms.Password__c; //登录用户密码
            urlConfirm += '&id='; //通过上面的URL查询出的最大ID号


            String rst = '20';
            Integer bCount = 0;
            //如果通知没有成功(成功返回值为0)，则循环
            while(rst != '0' && bCount < 5) {
                try {
                    bCount++;
                    String url = urlConfirm + maxID ;
                    System.debug('*** 回复读取确认URL: ' + url);
                    HttpRequest req = new HttpRequest();
                    req.setEndpoint(url);
                    req.setMethod('POST');
                    HttpResponse res = Utils.postRequest(req,5);

                    //返回结果样式：result=0&description=xxx
                    rst = res.getBody().split('&')[0].split('=')[1].trim();
                } catch(Exception ex) {}
            }
        }
    }
    */
    /************************************************************************
     * replys参数类：
     * mdn          手机号码
     * callmdn      接入号
     * content      回复内容
     * reply_time   回复时间，格式yyyy-MM-dd HH:mm:ss
     * id           回复id编号   
     ************************************************************************/
    /*
    class SmsReplyArgs {
        public String mdn;
        public String callmdn;
        public String content;
        public String reply_time;
        public Long id;
    }
    */
}